import js from "./javascript/index";

const analysisList:{[k:string]:any} = {};
export class LanguageAnalysis{
    data:{[k:string]:any} = {};

    loader:any;
    list:{[k:string]:any} = {};

    functionList:any[] = [];

    static use(obj:any){
        analysisList[obj.name] = obj.install();
    }

    static keys(){
        return Object.keys(analysisList);
    }

    analysis(node: {[k:string]:any},name:string){
        // 事件周期： 解析前，解析完，组装
        const analysis = analysisList[name];

        try{
            if(!analysis) throw new Error("不存在解析插件："+name);
            this.loader = analysis;
            this.list = node;

            this.commit("start");
            node.tree.forEach((index:number) => {
                this.functionList.push( this.next(index));
            });
            return this.commit("end");
        }
        catch(err){
            console.error(err);
        }
        
        return "";
    }

    commit(funName:string){
        let code="";
        this.loader.forEach((item:any)=>{
           if(item[funName])  code = item[funName].call(this,code);
        })

        return code;
    }

    next(index:any){
        if (index == -1) return "";

        const node = this.list.maps[index.index||index];
        let fun:any = null;
        if(index instanceof Number){
            fun = this.get( node.type );
        }
        else{
            fun = this.get( node.type );
        }

        if(fun instanceof Function) return fun(index,node);
        return "";
    }

    defaultNext(name:string,node:any,noString=true){
        if(noString) return this.next(node[name]) || this.variableConversion(node["default_"+name]);
        else return this.next(node[name]) || `"${node["default_"+name]}"`;
    }

    get(funName:string){
        let fun;
        this.loader.forEach((item:any)=>{
            if(item[funName])  fun = item[funName].bind(this);
        })

        return fun;
    }

    variableConversion(value:string){
        if(!value) return "null";
        value = value.trim();
        if(value == "") return null;
        if(value[0] == "+" || value[0] == ":") return `"${value.substring(1)}"`;
        // 数值
        if(/^-{0,1}[0-9]+\.{0,1}[0-9]*e{0,1}\+*[0-9]*$/.test(value)){
            return value;
        }
        if(/^(0x[a-fA-F0-9]+)|(0b[0-1]*)|(0o[0-7]*)$/.test(value)){
            return value;
        }
        // 布尔
        if(/^true|false$/.test(value)){
            return value;
        }
        // 属性选择
        if(/^[a-zA-Z_.$][0-9a-zA-Z_.$]*$/.test(value)){
            return value;
        }
        // 变量
        if(/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(value)){
            return value;
        }
        // 字符串
        return `"${value.replaceAll("\"",`\\"`)}"`;
    }
}

LanguageAnalysis.use(js);